package com.lanhai.mind.dispatch;

import com.lanhai.mind.beans.AgvBean;
import com.lanhai.mind.beans.AgvDataBean;
import com.lanhai.mind.beans.AgvMountBean;
import com.lanhai.mind.beans.DotBean;
import com.lanhai.mind.beans.InnerBean;
import com.lanhai.mind.dao.DeviceDao;
import com.lanhai.mind.enums.AgvCurrentTransEnum;
import com.lanhai.mind.enums.DotTypeEnum;
import com.lanhai.mind.enums.InnerCmdEnum;
import com.lanhai.mind.interfaces.IAgv; 
import com.lanhai.mind.interfaces.IAgvEvent;
import com.lanhai.mind.interfaces.IAgvMount;
import com.lanhai.mind.interfaces.IControlArea;
import com.lanhai.mind.interfaces.IDevice;
import com.lanhai.mind.interfaces.IDot;
import com.lanhai.mind.interfaces.IDotEvent;
import com.lanhai.mind.interfaces.ITempData; 

/**
 * 小车的消息处理
 * @author zhengwei
 *
 */
public class DispatchAgv {
	IAgv iAgv;
	IAgvMount iAgvMount;
	IAgvEvent iAgvEvent;
	ITempData iTempData;
	IDot iDot; 
	IDotEvent iDotEvent;
	IDevice iDevice;
	IControlArea iControlArea;
	
	
	public   void resolve(AgvDataBean data) {
		AgvBean agv=iAgv.getBean( data.getAgvId()); 
		if (agv == null) {
			// 对应的小车不存在
			//Tools.writeErrLog(String.format("没有找到IP为%s的小车",unit.getIp()));
			return;
		}
		switch (data.getType()) {
		case BZ:
			//// 避障 nothing 
			break;
		case CD:
			//// 充电 nothing 
			break;
		case DD:
			//// 到达
			
			if (iTempData.lockCmd(data.getAgvId(),data.getCmdStr()) == false) {
				// 只需要处理一次，强行return，防止括号内容过长
				return;
			}
			 
			//更新小车信息
			agv.setCurrentX(data.getX());
			agv.setCurrentY(data.getY());
			agv.setRoad(data.getRoad());
			 
			// 判断是否到主路
			if (data.getRoad() == 0) {
				DotBean transDot=iDot.getBean(agv.getCurrentDot()); 
				if (transDot != null) {
					// 小车去下一道工序  
					agv.setNextProcess( transDot.getNextProcess());
					agv.setNextDevice(transDot.getNextDevice());
					agv.setCurrentDot(0);
					iTempData.setDotOfAgv(  transDot.getDotNO(),agv.getAgvId());
					iAgv.saveCache(data.getAgvId(), agv);  
					iAgvEvent.toRoad(agv,  transDot.getTargetRoad()); 
				} 
				return; // 结束操作，不考虑后面的到达停泊位
			}
			
			
			DotBean cDot=iDot.getBeanByXY(data.getX(),data.getY());
			if(cDot==null) {
				// 到达了一个表中不存在的停泊位，这是一个数据BUG
				//Tools.writeErrLog(String.format("缺少坐标为【%d,%d】的点位",data.getX(),data.getY()));
				//StateQueue.Push(new StateData(0,agv.getAgvId()+"","到达错误点位")); 
				agv.setCurrentDot(-1);
				iAgv.saveCache(data.getAgvId(), agv); 
				return;
			}
			
			if(cDot.getDotType()!=DotTypeEnum.QrBefore) {
				//传输工位前二维码的区域，不做点更新
				agv.setCurrentDot(cDot.getDotNO());  
				iTempData.setDotOfAgv(  cDot.getDotNO(),agv.getAgvId());
			} 
			iAgv.saveCache(data.getAgvId(), agv); 
			
			
			//// 开始处理停泊位的各种类型
			if (cDot.getDotType() == DotTypeEnum.Power) {
				//// 充电点 
				iDotEvent.arrivedPower(agv, cDot);  
			} else if (cDot.getDotType() == DotTypeEnum.Wait) {
				//// 待命点 
				iDotEvent.arrivedWait(agv, cDot);
			} else if (cDot.getDotType() == DotTypeEnum.Trans) {
				//// 可传输工位 
				iDotEvent.arrivedTrans(agv, cDot);
			} else if (cDot.getDotType() == DotTypeEnum.Decide) {
				////分配点
				 iDotEvent.arrivedDecide(agv, cDot, data); 
			} else if (cDot.getDotType() == DotTypeEnum.TransOut) {
				//// 释放工位 
				 iDotEvent.arrivedRelease(agv, cDot ); 
			} else if (cDot.getDotType() == DotTypeEnum.Estimate) {
				//// 进入了预判断点 
				iDotEvent.arrivedEstimate(agv, cDot) ;
			}else if(cDot.getDotType()==DotTypeEnum.Route) {
				//路由点，直接行始小车
				if(cDot.getRouteRoad()>0) { 
					iAgvEvent.toRoad(agv,   cDot.getRouteRoad());  
				}else {
					//没有分配路由 
				}
			}
			break;
		case DM:
			// 待命 nothing 
			break;
		case JG:
			// 交管 
			if (iTempData.lockCmd(data.getAgvId(),data.getCmdStr()) ) { 	
				//保存状态 
				agv.setCurrentX(data.getX());
				agv.setCurrentY(data.getY());
				agv.setRoad(data.getRoad());
				iAgv.saveCache(data.getAgvId(), agv); 
			}
			break;
		case JT:
			// 急停
			if (iTempData.lockCmd(data.getAgvId(),data.getCmdStr()) ) {
				agv.setCurrentX(data.getX());
				agv.setCurrentY(data.getY());
				agv.setRoad(data.getRoad());
				iAgv.saveCache(data.getAgvId(), agv); 
			}
			break;
		case KCS:
			// 可传输,发起调度
		    NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			break;
		case LX:
			// 离线 
			break;
		case SCCW: 
			//上层传出完成 
			AgvMountBean mountuo=iAgvMount.getBean(agv.getAgvId());
			if(mountuo==null) {
				mountuo=new AgvMountBean();
				mountuo.setAgvId(agv.getAgvId()); 
			}
			mountuo.setUpFull(false); 
			mountuo.setUpHasTrans(true); 
			iAgvMount.saveCache(agv.getAgvId(), mountuo); 
			agv.setCurrentTrans(AgvCurrentTransEnum.None);
			iAgv.saveCache(agv.getAgvId(), agv);
			//调度 
			NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			 
			break;
		case SCRW:
			//上层传入完成 
			AgvMountBean mountui=iAgvMount.getBean(agv.getAgvId());
			if(mountui==null) {
				mountui=new AgvMountBean();
				mountui.setAgvId(agv.getAgvId()); 
			}
			mountui.setUpFull(true); 
			mountui.setUpHasTrans(true); 
			iAgvMount.saveCache(agv.getAgvId(), mountui); 
			agv.setCurrentTrans(AgvCurrentTransEnum.None);
			iAgv.saveCache(agv.getAgvId(), agv);
			//调度
			NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			break;
		case SCXRW:
			//上出下入完成 
			AgvMountBean mounta1=iAgvMount.getBean(agv.getAgvId());
			if(mounta1==null) {
				mounta1=new AgvMountBean();
				mounta1.setAgvId(agv.getAgvId()); 
			}
			mounta1.setUpFull(false); 
			mounta1.setDownFull(true); 
			mounta1.setUpHasTrans(true); 
			mounta1.setDownHasTrans(true); 
			iAgvMount.saveCache(agv.getAgvId(), mounta1); 
			agv.setCurrentTrans(AgvCurrentTransEnum.None);
			iAgv.saveCache(agv.getAgvId(), agv);
			//调度
			NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			break; 
		case SRXCW:
			//上入下出完成 
			AgvMountBean mounta2=iAgvMount.getBean(agv.getAgvId());
			if(mounta2==null) {
				mounta2=new AgvMountBean();
				mounta2.setAgvId(agv.getAgvId()); 
			}
			mounta2.setUpFull(true); 
			mounta2.setDownFull(false); 
			mounta2.setUpHasTrans(true); 
			mounta2.setDownHasTrans(true); 
			iAgvMount.saveCache(agv.getAgvId(), mounta2); 
			agv.setCurrentTrans(AgvCurrentTransEnum.None);
			iAgv.saveCache(agv.getAgvId(), agv);
			//调度
			NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			break; 
		case XCCW:
			//下层传出完成
			//StateQueue.Push(new StateData(0,agv.getAgvId()+"","下层传出完成")); 
			AgvMountBean mount1=iAgvMount.getBean(agv.getAgvId());
			if(mount1==null) {
				mount1=new AgvMountBean();
				mount1.setAgvId(agv.getAgvId());
				mount1.setUpHasTrans(true);
			}
			mount1.setDownHasTrans(true); 
			mount1.setDownFull(false); 
			iAgvMount.saveCache(agv.getAgvId(), mount1); 
			agv.setCurrentTrans(AgvCurrentTransEnum.None);
			iAgv.saveCache(agv.getAgvId(), agv);
			//调度
			NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			break;
		case XCRW:
			//下层传入完成 
			AgvMountBean mount2=iAgvMount.getBean(agv.getAgvId());
			if(mount2==null) {
				mount2=new AgvMountBean();
				mount2.setAgvId(agv.getAgvId());
				mount2.setUpHasTrans(true);
			}
			mount2.setDownHasTrans(true); 
			mount2.setDownFull(true); 
			iAgvMount.saveCache(agv.getAgvId(), mount2);  
			agv.setCurrentTrans(AgvCurrentTransEnum.None);
			iAgv.saveCache(agv.getAgvId(), agv);
			//调度
			NoticeJudgement(agv.getAgvId(),agv.getCurrentDot());
			break; 
		case ZXWC:
			// 装卸完成 nothing
			break;
		case TZ:
			// 停止
			if (iTempData.lockCmd(data.getAgvId(),data.getCmdStr()) ) {
				agv.setCurrentX(data.getX());
				agv.setCurrentY(data.getY());
				agv.setRoad(data.getRoad());
				iAgv.saveCache(data.getAgvId(), agv); 
			}
			break;
		case ERR:
			// 异常了 
			break;
		case XS:
			// 行驶中
			 
			agv.setCurrentX(data.getX());
			agv.setCurrentY(data.getY());
			agv.setRoad(data.getRoad());
			iAgv.saveCache(data.getAgvId(), agv); 
			  
			int areaID = iControlArea.getAreaId(data.getX(), data.getY());
			if (areaID > 0) {
				if (agv.getAreaId() == areaID) {
					//小车自身锁
					return;
				} 
				if (iControlArea.isService(areaID)) {
					//// 进入了故障服务区,释放所有的资源
					iAgvEvent.releaseAllResource(agv); 
					return;
				} 
				// 进入交管区
				agv.setAreaId(areaID); 
				if (iControlArea.lockArea(areaID, agv.getAgvId())) {
					// 锁住区域成功,更新当前区域id  继续前进  
				} else {
					// 需要停下来
					iControlArea.addStopAgv(areaID, agv.getAgvId());  
					// 向小车发送停车的指令
					iAgvEvent.stopOrstart(agv,   true); 
				}
			} else {
				// 离开交管区 
				if (agv.getAreaId() > 0) {
					agv.setAreaId(0);
					iAgv.saveCache(agv.getAgvId(), agv);  
					iControlArea.unlockArea(agv.getAreaId()); 
					return;
				}
			}
			
			//保存状态
			iAgv.saveCache(agv.getAgvId(), agv);  
			break;
		default:
			break;

		}
	}
	
	void NoticeJudgement(int agvid,int dotNO) {
		DeviceDao dao=iDevice.getDaoByDot(dotNO); 
		if(dao==null) return;
		
		 
		InnerBean  bean=new InnerBean();
		bean.setAgvid(agvid);
		bean.setDeviceid(dao.getDeviceid());
		bean.setCmd(InnerCmdEnum.Judgement);
	}
	 
}
